home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 52 / Amiga Format AFCD52 (Issue 136, May 2000).iso / -serious- / programming / other / dopus412-gpl / library / dopus_stuff.c < prev    next >
C/C++ Source or Header  |  2000-02-28  |  37KB  |  1,258 lines

  1. /*
  2.  
  3. Directory Opus 4
  4. Original GPL release version 4.12
  5. Copyright 1993-2000 Jonathan Potter
  6.  
  7. This program is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU General Public License
  9. as published by the Free Software Foundation; either version 2
  10. of the License, or (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. All users of Directory Opus 4 (including versions distributed
  22. under the GPL) are entitled to upgrade to the latest version of
  23. Directory Opus version 5 at a reduced price. Please see
  24. http://www.gpsoft.com.au for more information.
  25.  
  26. The release of Directory Opus 4 under the GPL in NO WAY affects
  27. the existing commercial status of Directory Opus 5.
  28.  
  29. */
  30.  
  31. #include "dopuslib.h"
  32. #include "config.h"
  33. #include "configflags.h"
  34.  
  35. char *getstringcopy(char *);
  36. readline(char *,int,char *,int);
  37. void DoAssignDrive(struct ConfigStuff *,int,char *,char *);
  38. void linkinnewfiletype(struct ConfigStuff *,struct dopusfiletype *);
  39. writestring(int,char *);
  40. void freestring(char *);
  41.  
  42. __asm __saveds DoReadConfig(register __a0 char *name,
  43.     register __a1 struct ConfigStuff *cstuff)
  44. {
  45.     int a,in,size,pos,b,bk,gad,mv;
  46.     USHORT ver,mag;
  47.     char *cbuf,*buf,*tbuf,buf2[102],buf3[102];
  48.     struct dopusfiletype *newtype;
  49.     struct olddopusfiletype otype;
  50.     struct dopusgadgetbanks *bank=NULL,*temp;
  51.     struct Config *config;
  52.     struct DOpusRemember *key;
  53.     struct dopusfunction *tempfunc;
  54.     struct dopusdrive *driveptr;
  55.     struct dopushotkey *hotkey,*curhotkey=NULL;
  56.  
  57.     if (!(config=cstuff->config)) return(-1);
  58.  
  59.     DoFreeConfig(cstuff);
  60.     if (DoCheckExist(name,&size)>=0) return(ERROR_OBJECT_NOT_FOUND);
  61.     size-=sizeof(struct Config);
  62.     if (!(in=Open(name,MODE_OLDFILE))) return(IoErr());
  63.     if ((Read(in,(char *)&ver,2))<2 || (Read(in,(char *)&mag,2))<2 ||
  64.         mag!=CONFIG_MAGIC || ver==0xde) {
  65.         if (mag==CONFIG_MAGIC && ver==0xde) {
  66.             struct DOpusSimpleRequest req;
  67.             char *gads[2];
  68.             int rets[1];
  69.  
  70.             req.text="Pre-3.32 configuration files not recognised!";
  71.             gads[0]="Continue"; gads[1]=NULL;
  72.             rets[0]=0;
  73.             req.gads=gads;
  74.             req.rets=rets;
  75.             req.hi=-1; req.lo=-1;
  76.             req.fg=-1; req.bg=-1;
  77.             req.strbuf=NULL;
  78.             req.flags=SRF_BORDERS;
  79.             req.font=GfxBase->DefaultFont;
  80.             req.title="Request";
  81.  
  82.             DoSimpleRequest(NULL,&req);
  83.         }
  84.         Close(in);
  85.         return(ERROR_NOT_CONFIG);
  86.     }
  87.     Seek(in,0,OFFSET_BEGINNING);
  88.     if ((Read(in,(char *)config,sizeof(struct Config)))<sizeof(struct Config)) {
  89.         Close(in);
  90.         return(IoErr());
  91.     }
  92.  
  93.     if (config->version<CONFIG_CHANGE_DISPLAY) {
  94.         for (a=0;a<2;a++) {
  95.             for (b=0;b<8;b++) {
  96.                 config->displaypos[a][b]=config->old_displaypos[a][b];
  97.                 config->displaylength[a][b]=config->old_displaylength[a][b];
  98.                 config->old_displaypos[a][b]=0;
  99.                 config->old_displaylength[a][b]=0;
  100.             }
  101.             for (b=8;b<16;b++) {
  102.                 config->displaypos[a][b]=-1;
  103.                 config->displaylength[a][b]=0;
  104.             }
  105.         }
  106.     }
  107.  
  108.     if (config->version<CONFIG_CHANGE_CONFIGXY) {
  109.         config->config_x=-1;
  110.         config->config_y=-1;
  111.     }
  112.  
  113.     if (config->version<CONFIG_CHANGE_DIMENS) {
  114.         config->scr_winx=config->wbwinx;
  115.         config->scr_winy=config->wbwiny;
  116.         config->scr_winw=config->scrw;
  117.         config->scr_winh=config->scrh;
  118.         config->pubscreen_name[0]=0;
  119.     }
  120.  
  121.     if (config->version<CONFIG_NEW_SLIDERS) {
  122.         config->slider_pos=1;
  123.     }
  124.  
  125.     if (config->version<=OLD_CONFIG_VERSION) {
  126.         config->scrdepth+=2;
  127.         config->dateformat=1;
  128.         for (a=0;a<2;a++) {
  129.             for (b=0;b<5;b++) config->displaypos[a][b]=b;
  130.             for (b=5;b<16;b++) config->displaypos[a][b]=-1;
  131.             config->displaylength[a][0]=28;
  132.             config->displaylength[a][1]=80;
  133.             config->displaylength[a][2]=40;
  134.             config->displaylength[a][3]=32;
  135.             config->displaylength[a][4]=32;
  136.             config->sortmethod[a]=0;
  137.             config->separatemethod[a]=1;
  138.         }
  139.         config->sortflags=0;
  140.         config->scrclktype=SCRCLOCK_MEMORY|SCRCLOCK_DATE|SCRCLOCK_TIME;
  141.         if (config->icontype==3) config->icontype=ICON_NOWINDOW;
  142.         else config->icontype=0;
  143.         config->icontype|=ICON_MEMORY|ICON_DATE|ICON_TIME;
  144.         config->showfree=1<<config->showfree;
  145.         config->hotkeyqual=config->hotkeycode&0xff;
  146.         config->hotkeycode>>=8;
  147.         config->stringfgcol=1; config->stringbgcol=0;
  148.         config->stringselfgcol=1; config->stringselbgcol=0;
  149.     }
  150.     if (config->version<=CONFIG_CHANGE_PALETTE) {
  151.         for (a=0,b=0;a<16;a++) {
  152.             config->new_palette[b++]=(((config->Palette[a]>>8)&0xf)<<28)|0x0fffffff;
  153.             config->new_palette[b++]=(((config->Palette[a]>>4)&0xf)<<28)|0x0fffffff;
  154.             config->new_palette[b++]=((config->Palette[a]&0xf)<<28)|0x0fffffff;
  155.         }
  156.     }
  157.     if (config->version<=CONFIG_CHANGE_BUFCOUNT) {
  158.         config->bufcount/=2;
  159.         if (config->bufcount<1) config->bufcount=1;
  160.     }
  161.     if (config->version<CONFIG_LESS_DODRIVES) {
  162.         if (!(tempfunc=AllocMem(sizeof(struct dopusfunction)*DRIVECOUNT,MEMF_CLEAR))) {
  163.             Close(in);
  164.             return(ERROR_NO_FREE_STORE);
  165.         }
  166.         driveptr=(struct dopusdrive *)config->drive;
  167.         for (a=0;a<OLDDRIVECOUNT;a++) {
  168.             strcpy(tempfunc[a].name,driveptr[a].name);
  169.             tempfunc[a].key=driveptr[a].key;
  170.             tempfunc[a].qual=driveptr[a].qual;
  171.             tempfunc[a].fpen=driveptr[a].fpen;
  172.             tempfunc[a].bpen=driveptr[a].bpen;
  173.             tempfunc[a].function=getstringcopy(driveptr[a].path);
  174.         }
  175.         for (a=OLDDRIVECOUNT;a<DRIVECOUNT;a++) tempfunc[a].fpen=3;
  176.         CopyMem((char *)tempfunc,(char *)driveptr,sizeof(struct dopusfunction)*DRIVECOUNT);
  177.         FreeMem(tempfunc,sizeof(struct dopusfunction)*DRIVECOUNT);
  178.     }
  179.     if (config->version<=CONFIG_CHANGE_DOSREQ) {
  180.         config->errorflags^=1;
  181.         config->hotkeyflags=0;
  182.         config->pad3=config->pad4=config->pad8=0;
  183.         for (a=0;a<2;a++) config->pad5[a]=config->pad7[a]=0;
  184.         for (a=0;a<232;a++) config->morepadding[a]=0;
  185.         for (a=0;a<2;a++) {
  186.             config->scrollborders[a].MinX=~0;
  187.             config->scrollborders[a].MaxX=~0;
  188.             config->scrollborders[a].MinY=~0;
  189.             config->scrollborders[a].MaxY=~0;
  190.         }
  191.         config->generalscreenflags=2;
  192.     }
  193.     if (config->version<=CONFIG_NEW_FUNCTIONS) {
  194.         for (a=0;a<MENUCOUNT;a++) {
  195.             strcpy(buf2,(char *)&config->menu[a]);
  196.             config->menu[a].name=getstringcopy(buf2);
  197.             config->menu[a].pad2[0]=0;
  198.             config->menu[a].pad2[1]=0;
  199.             config->menu[a].pad2[2]=0;
  200.         }
  201.     }
  202.     if (config->version<=CONFIG_CHANGE_ARROWS)
  203.         for (a=0;a<3;a++) config->arrowsize[a]=8;
  204.     if (config->version<=CONFIG_CHANGE_EXTERN) {
  205.         for (a=0;a<80;a++) config->pad5a[a]=config->configreturnscript[a]=0;
  206.         for (a=0;a<397;a++) config->pad9a[a]=0;
  207.         config->loadexternal=0;
  208.     }
  209.  
  210.     key=NULL;
  211.     if (!(cbuf=(char *)LAllocRemember(&key,size,MEMF_CLEAR)) ||
  212.         !(buf=(char *)LAllocRemember(&key,4096,MEMF_CLEAR)) ||
  213.         !(tbuf=(char *)LAllocRemember(&key,256,MEMF_CLEAR))) {
  214.         Close(in);
  215.         LFreeRemember(&key); 
  216.         return(ERROR_NO_FREE_STORE);
  217.     }
  218.     Read(in,cbuf,size);
  219.     Close(in);
  220.  
  221.     for (a=0;a<MENUCOUNT;a++) {
  222.         config->menu[a].function=NULL;
  223.         if (config->version>CONFIG_NEW_FUNCTIONS) config->menu[a].name=NULL;
  224.     }
  225.     if (config->version>OLD_CONFIG_VERSION) {
  226.         for (a=0;a<DRIVECOUNT;a++) config->drive[a].function=NULL;
  227.     }
  228.  
  229.     pos=0;
  230.     for (a=0;a<MENUCOUNT;a++) {
  231.         pos=readline(cbuf,pos,buf,size);
  232.         if (buf[0]) DoAssignMenu(cstuff,a,(char *)-1,buf);
  233.         if (pos==-1) goto endthis;
  234.     }
  235.     if (config->version>CONFIG_NEW_FUNCTIONS) {
  236.         for (a=0;a<MENUCOUNT;a++) {
  237.             pos=readline(cbuf,pos,buf,size);
  238.             if (buf[0]) DoAssignMenu(cstuff,a,buf,(char *)-1);
  239.             if (pos==-1) goto endthis;
  240.         }
  241.     }
  242.  
  243.     if (config->version>OLD_CONFIG_VERSION) {
  244.         for (a=0;a<DRIVECOUNT;a++) {
  245.             pos=readline(cbuf,pos,buf,size);
  246.             if (buf[0]) DoAssignDrive(cstuff,a,(char *)-1,buf);
  247.             if (pos==-1) goto endthis;
  248.         }
  249.     }
  250.     else {
  251.         for (a=0;a<ARCHIVECOUNT;a++) pos=readline(cbuf,pos,buf,size);
  252.     }
  253.  
  254.     bk=-1;
  255.     FOREVER {
  256.         if (pos>=size || pos==-1) break;
  257.         if (cbuf[pos]==5 && cbuf[pos+1]=='H') {
  258.             pos+=2;
  259.             if ((pos+sizeof(struct dopushotkey))>=size) break;
  260.             if ((hotkey=AllocMem(sizeof(struct dopushotkey),MEMF_CLEAR))) {
  261.                 CopyMem((char *)&cbuf[pos],(char *)hotkey,sizeof(struct dopushotkey));
  262.                 hotkey->func.function=NULL;
  263.                 hotkey->next=NULL;
  264.             }
  265.             pos+=sizeof(struct dopushotkey);
  266.             if ((pos=readline(cbuf,pos,buf,size))==-1) break;
  267.             if (hotkey) {
  268.                 hotkey->func.function=getstringcopy(buf);
  269.                 if (curhotkey) curhotkey->next=hotkey;
  270.                 else cstuff->firsthotkey=hotkey;
  271.                 curhotkey=hotkey;
  272.             }
  273.         }
  274.         else if (cbuf[pos]==6 && cbuf[pos+1]=='F') {
  275.             pos+=2;
  276.             if ((pos+sizeof(struct wr_dopusfiletype))>=size) break;
  277.             if ((newtype=(struct dopusfiletype *)
  278.                 LAllocRemember(&cstuff->typekey,sizeof(struct dopusfiletype),MEMF_CLEAR))) {
  279.                 CopyMem((char *)&cbuf[pos],(char *)newtype,sizeof(struct wr_dopusfiletype));
  280.                 if (config->version<=CONFIG_CHANGE_FTYPE) {
  281.                     newtype->type[31]=0;
  282.                     newtype->typeid[0]=0;
  283.                 }
  284.                 pos+=sizeof(struct wr_dopusfiletype);
  285.                 newtype->recognition=NULL;
  286.                 for (a=0;a<FILETYPE_FUNCNUM;a++) newtype->function[a]=NULL;
  287.                 if ((pos=readline(cbuf,pos,buf,size))==-1) break;
  288.                 if ((newtype->recognition=LAllocRemember(&cstuff->typekey,strlen(buf)+1,0)))
  289.                     strcpy(newtype->recognition,buf);
  290.                 for (a=0;a<FILETYPE_FUNCNUM;a++) {
  291.                     if ((pos=readline(cbuf,pos,buf,size))==-1) break;
  292.                     if ((newtype->function[a]=LAllocRemember(&cstuff->typekey,strlen(buf)+1,0)))
  293.                         strcpy(newtype->function[a],buf);
  294.                 }
  295.                 newtype->iconpath=NULL;
  296.                 if (config->version>CONFIG_CHANGE_FILETYPE) {
  297.                     pos=readline(cbuf,pos,buf,size);
  298.                     if (buf[0] && (newtype->iconpath=LAllocRemember(&cstuff->typekey,strlen(buf)+1,0)))
  299.                         strcpy(newtype->iconpath,buf);
  300.                 }
  301.                 linkinnewfiletype(cstuff,newtype);
  302.             }
  303.         }
  304.         else if (cbuf[pos]==1 && cbuf[pos+1]=='F') {
  305.             pos+=2;
  306.             if ((pos+sizeof(struct olddopusfiletype))>=size) break;
  307.             if ((newtype=(struct dopusfiletype *)
  308.                 LAllocRemember(&cstuff->typekey,sizeof(struct dopusfiletype),MEMF_CLEAR))) {
  309.                 CopyMem((char *)&cbuf[pos],(char *)&otype,sizeof(struct olddopusfiletype));
  310.                 pos+=sizeof(struct olddopusfiletype);
  311.                 LStrnCpy(newtype->type,otype.type,32);
  312.                 newtype->type[31]=0;
  313.                 newtype->typeid[0]=0;
  314.                 for (a=0;a<FILETYPE_FUNCNUM;a++) newtype->function[a]=NULL;
  315.                 for (a=0;a<4;a++) {
  316.                     strncpy(newtype->actionstring[a],otype.actionstring[a],39);
  317.                     newtype->actionstring[a][39]=0;
  318.                     newtype->which[a]=otype.which[a];
  319.                     newtype->stack[a]=otype.stack[a];
  320.                     newtype->pri[a]=otype.pri[a];
  321.                     newtype->delay[a]=otype.delay[a];
  322.                 }
  323.                 for (a=4;a<FILETYPE_FUNCNUM;a++) {
  324.                     newtype->stack[a]=4000;
  325.                     newtype->delay[a]=2;
  326.                 }
  327.                 for (a=0;a<4;a++) {
  328.                     if ((pos=readline(cbuf,pos,buf,size))==-1) break;
  329.                     if ((newtype->function[a]=LAllocRemember(&cstuff->typekey,strlen(buf)+1,MEMF_CLEAR)))
  330.                         strcpy(newtype->function[a],buf);
  331.                 }
  332.                 buf[0]=0;
  333.                 if (otype.filepat[0])
  334.                     LSprintf(buf,"%lc%s%lc",FTYC_MATCHNAME,otype.filepat,
  335.                         ((otype.recogchars[0])?((otype.and)?FTYC_AND:FTYC_OR):FTYC_ENDSECTION));
  336.                 if (otype.recogchars[0]) {
  337.                     b=mv=0;
  338.                     for (a=0;a<100;a++) {
  339.                         if (!otype.recogchars[a] || otype.recogchars[a]==',') {
  340.                             buf2[b]=0;
  341.                             if (mv==0) {
  342.                                 if ((b=Atoh(buf2,0))>0) {
  343.                                     LSprintf(buf3,"%lc%ld%lc",FTYC_MOVETO,b,FTYC_ENDSECTION);
  344.                                     StrConcat(buf,buf3,4096);
  345.                                 }
  346.                                 mv=1;
  347.                             }
  348.                             else {
  349.                                 LSprintf(buf3,"%lc$%s%lc",FTYC_MATCH,buf2,FTYC_AND);
  350.                                 StrConcat(buf,buf3,4096);
  351.                                 mv=0;
  352.                             }
  353.                             if (!otype.recogchars[a]) break;
  354.                             b=0;
  355.                         }
  356.                         else {
  357.                             if (mv==1 && otype.recogchars[a]=='.') {
  358.                                 buf2[b++]='?'; buf2[b++]='?';
  359.                             }
  360.                             else buf2[b++]=otype.recogchars[a];
  361.                         }
  362.                     }
  363.                     b=strlen(buf);
  364.                     if (buf[b-1]==FTYC_AND) buf[b-1]=0;
  365.                 }
  366.                 if ((newtype->recognition=LAllocRemember(&cstuff->typekey,strlen(buf)+1,MEMF_CLEAR)))
  367.                     strcpy(newtype->recognition,buf);
  368.                 linkinnewfiletype(cstuff,newtype);
  369.             }
  370.         }
  371.         else if ((cbuf[pos]==2 || cbuf[pos]==3) && cbuf[pos+1]=='G') {
  372.             if (cbuf[pos]==2) {
  373.                 a=0;
  374.                 b=sizeof(struct olddopusgadget)*GADCOUNT;
  375.             }
  376.             else {
  377.                 a=1;
  378.                 b=sizeof(struct newdopusfunction)*GADCOUNT;
  379.             }
  380.             pos+=2;
  381.             if ((pos+b)>=size) break;
  382.             ++bk;
  383.             if (!(temp=AllocMem(sizeof(struct dopusgadgetbanks),MEMF_CLEAR))) goto endthis;
  384.             if (!cstuff->firstbank) cstuff->firstbank=temp;
  385.             else bank->next=temp;
  386.             bank=temp;
  387.             if (a) {
  388.                 CopyMem((char *)&cbuf[pos],(char *)bank->gadgets,sizeof(struct newdopusfunction)*GADCOUNT);
  389.                 pos+=(sizeof(struct newdopusfunction)*GADCOUNT);
  390.             }
  391.             else {
  392.                 for (a=0;a<GADCOUNT;a++) {
  393.                     CopyMem((char *)&cbuf[pos],(char *)&bank->gadgets[a],10);
  394.                     CopyMem((char *)&cbuf[pos+10],(char *)&bank->gadgets[a].which,16);
  395.                     pos+=sizeof(struct olddopusgadget);
  396.                 }
  397.             }
  398.             for (gad=0;gad<GADCOUNT;gad++) {
  399.                 bank->gadgets[gad].function=NULL;
  400.                 buf[0]=0;
  401.                 if (pos>-1) {
  402.                     pos=readline(cbuf,pos,buf,size);
  403.                     DoAssignGadget(cstuff,bk,gad,(char *)-1,buf);
  404.                 }
  405.             }
  406.             if (config->version>CONFIG_NEW_FUNCTIONS) {
  407.                 for (gad=0;gad<GADCOUNT;gad++) {
  408.                     bank->gadgets[gad].name=NULL;
  409.                     buf[0]=0;
  410.                     if (pos>-1) {
  411.                         pos=readline(cbuf,pos,buf,size);
  412.                         DoAssignGadget(cstuff,bk,gad,buf,(char *)-1);
  413.                     }
  414.                 }
  415.             }
  416.             else {
  417.                 for (gad=0;gad<GADCOUNT;gad++) {
  418.                     strcpy(buf,(char *)&bank->gadgets[gad]);
  419.                     bank->gadgets[gad].name=getstringcopy(buf);
  420.                     bank->gadgets[gad].pad2[0]=0;
  421.                     bank->gadgets[gad].pad2[1]=0;
  422.                     bank->gadgets[gad].pad2[2]=0;
  423.                 }
  424.             }
  425.             if (pos==-1) break;
  426.         }
  427.     }
  428. endthis:
  429.     LFreeRemember(&key);
  430.     cstuff->curbank=cstuff->firstbank;
  431.     return(1);
  432. }
  433.  
  434. char *getstringcopy(str)
  435. char *str;
  436. {
  437.     char *newstr=NULL;
  438.  
  439.     if (str && (newstr=AllocMem(strlen(str)+1,0)))
  440.         strcpy(newstr,str);
  441.     return(newstr);
  442. }
  443.  
  444. __asm __saveds DoSaveConfig(register __a0 char *name,
  445.     register __a1 struct ConfigStuff *cstuff)
  446. {
  447.     int a,out,ret=0;
  448.     struct dopusfiletype *type;
  449.     struct dopushotkey *hotkey;
  450.     struct dopusgadgetbanks *bank;
  451.     struct Config *config;
  452.  
  453.     if (!(config=cstuff->config)) return(0);
  454.  
  455.     config->version=CONFIG_VERSION;
  456.     config->magic=CONFIG_MAGIC;
  457.  
  458.     if (!(out=Open(name,MODE_NEWFILE))) return(FALSE);
  459.     if ((Write(out,(char *)config,sizeof(struct Config)))<sizeof(struct Config)) {
  460.         Close(out);
  461.         return(0);
  462.     }
  463.     for (a=0;a<MENUCOUNT;a++)
  464.         if (!writestring(out,config->menu[a].function)) goto error;
  465.     for (a=0;a<MENUCOUNT;a++)
  466.         if (!writestring(out,config->menu[a].name)) goto error;
  467.     for (a=0;a<DRIVECOUNT;a++)
  468.         if (!writestring(out,config->drive[a].function)) goto error;
  469.  
  470.     type=cstuff->firsttype;
  471.     while (type) {
  472.         if ((Write(out,"\006F",2))<2) goto error;
  473.         if ((Write(out,(char *)type,sizeof(struct wr_dopusfiletype)))<sizeof(struct wr_dopusfiletype))
  474.             goto error;
  475.         if (!writestring(out,type->recognition)) goto error;
  476.         for (a=0;a<FILETYPE_FUNCNUM;a++)
  477.             if (!writestring(out,type->function[a])) goto error;
  478.         if (!writestring(out,type->iconpath)) goto error;
  479.         type=type->next;
  480.     }
  481.     bank=cstuff->firstbank;
  482.     while (bank) {
  483.         if ((Write(out,"\003G",2))<2) goto error;
  484.         if ((Write(out,(char *)bank->gadgets,sizeof(struct dopusfunction)*GADCOUNT))<
  485.             sizeof(struct dopusfunction)*GADCOUNT) goto error;
  486.         for (a=0;a<GADCOUNT;a++)
  487.             if (!writestring(out,bank->gadgets[a].function)) goto error;
  488.         for (a=0;a<GADCOUNT;a++)
  489.             if (!writestring(out,bank->gadgets[a].name)) goto error;
  490.         bank=bank->next;
  491.     }
  492.     hotkey=cstuff->firsthotkey;
  493.     while (hotkey) {
  494.         if ((Write(out,"\005H",2))<2) goto error;
  495.         if ((Write(out,(char *)hotkey,sizeof(struct dopushotkey)))<sizeof(struct dopushotkey))
  496.             goto error;
  497.         if (!writestring(out,hotkey->func.function)) goto error;
  498.         hotkey=hotkey->next;
  499.     }
  500.     ret=1;
  501. error:
  502.     Close(out);
  503.     return(ret);
  504. }
  505.  
  506. writestring(file,string)
  507. int file;
  508. char *string;
  509. {
  510.     int b;
  511.     char nl=0;
  512.  
  513.     if (string) {
  514.         if ((Write(file,string,(b=(strlen(string)+1))))<b) return(0);
  515.     }
  516.     else Write(file,&nl,1);
  517.     return(1);
  518. }
  519.  
  520. struct DefaultGadFlag {
  521.     char code;
  522.     char qual;
  523.     char fpen;
  524.     char bpen;
  525. };
  526.  
  527. static ULONG defaultpalette[48]={
  528.     0xafffffff,0xafffffff,0xafffffff,
  529.     0x00000000,0x00000000,0x00000000,
  530.     0xffffffff,0xffffffff,0xffffffff,
  531.     0x0fffffff,0x5fffffff,0xbfffffff,
  532.     0xefffffff,0xafffffff,0x4fffffff,
  533.     0x7fffffff,0x00000000,0x7fffffff,
  534.     0xffffffff,0xffffffff,0x00000000,
  535.     0xcfffffff,0x2fffffff,0x00000000,
  536.     0xffffffff,0x8fffffff,0x00000000,
  537.     0xffffffff,0x00000000,0xffffffff,
  538.     0x9fffffff,0x6fffffff,0x3fffffff,
  539.     0x00000000,0xffffffff,0x9fffffff,
  540.     0x4fffffff,0xffffffff,0x3fffffff,
  541.     0x00000000,0x00000000,0x00000000,
  542.     0xffffffff,0xffffffff,0xffffffff,
  543.     0x2fffffff,0x5fffffff,0x9fffffff};
  544.  
  545. static char
  546.     *defgads[42]={
  547.         "All","Copy","Makedir","Hunt","Run","Comment","Read",
  548.         "None","Move","Assign","Search","","Datestamp","Hex Read",
  549.         "Parent","Rename","Check Fit","","","Protect","Show",
  550.         "Root","","GetSizes","","","Icon Info","Play",
  551.         "","","","","","Arc Ext","Edit",
  552.         "","DELETE","","","","Encrypt","Print"},
  553.     *revgads[35]={
  554.         "Toggle","Copy As","","","","","ANSI Read",
  555.         "","Move As","","","","","",
  556.         "","Clone","","","","","",
  557.         "","","ClearSizes","","","Add Icon","Loop Play",
  558.         "","","","","","","New File"},
  559.     *deffuncs[42]={
  560.         "*All","*Copy","*Makedir","*Hunt","*Run","*Comment","*Read",
  561.         "*None","*Move","*Assign","*Search","","*Datestamp","*HexRead",
  562.         "*Parent","*Rename","*CheckFit","","","*Protect","*Show",
  563.         "*Root","","*GetSizes","","","*IconInfo","*Play",
  564.         "","","","","","*User1","Ed {f}",
  565.         "","*DELETE","","","","*Encrypt","*Print"},
  566.     *revfuncs[35]={
  567.         "*Toggle","*CopyAs","","","","","*ANSIRead",
  568.         "","*MoveAs","","","","","",
  569.         "","*Clone","","","","","",
  570.         "","","*ClearSizes","","","*AddIcon","*LoopPlay",
  571.         "","","","","","","Ed {RsEnter filename to create new file:Untitled}"},
  572.  
  573.     *defmenus1[9]={
  574.         "Current dir~","Help!","Error help~",
  575.         "Configure~","About",
  576.         "Version~","Iconify","Button Iconify","Quit"},
  577.     *deffuncs1[9]={
  578.         "*CD","*Help","*ErrorHelp",
  579.         "*Configure","*About",
  580.         "*Version","*Iconify","*ButtonIconify","*Quit"},
  581.     *defmenus2[9]={
  582.         "Disk copy","Format","Install~","Relabel","Print dir","Disk info~",
  583.         "LHA add","Arc add","Zoo add"},
  584.     *deffuncs2[9]={
  585.         "*Diskcopy","*Format","*Install","*Relabel","*PrintDir","*DiskInfo",
  586.         "LHA -x a \"{d}{RsEnter LHA archive name}\" {O}",
  587.         "Arc a \"{d}{RsEnter Arc archive name}\" {O}",
  588.         "Zoo a \"{d}{RsEnter Zoo archive name}\" {O}"},
  589.  
  590.     *deftype_type[5]={
  591.         "LHA archive","ARC archive","ZOO archive","Icon","Default"},
  592.     *deftype_typeid[5]={
  593.         "LHA","ARC","ZOO","ICON","DEFAULT"},
  594.     *deftype_recog[6]={
  595.         "\002*.(lzh|lha)",
  596.         "\002*.arc",
  597.         "\002*.zoo",
  598.         "\001$E310\376\002*.info",
  599.         "\002*"},
  600.     *deftype_funcs[5][4]={
  601.         {"LHA v {f}","LHA -x -M x {f}","LHA v {f}","LHA -x -M x {f}"},
  602.         {"Arc v {f}","Arc x {f}","Arc v {f}","Arc x {f}"},
  603.         {"Zoo v {f}","Zoo x// {f}","Zoo v {f}","Zoo x// {f}"},
  604.         {"*IconInfo",NULL,NULL,NULL},
  605.         {"*SmartRead","*Copy",NULL,NULL}},
  606.     deftype_funcpos[5][4]={
  607.         {FTFUNC_DOUBLECLICK,FTFUNC_CLICKMCLICK,FTFUNC_READ,FTFUNC_AUTOFUNC1},
  608.         {FTFUNC_DOUBLECLICK,FTFUNC_CLICKMCLICK,FTFUNC_READ,FTFUNC_AUTOFUNC1},
  609.         {FTFUNC_DOUBLECLICK,FTFUNC_CLICKMCLICK,FTFUNC_READ,FTFUNC_AUTOFUNC1},
  610.         {FTFUNC_DOUBLECLICK},
  611.         {FTFUNC_DOUBLECLICK,FTFUNC_CLICKMCLICK}},
  612.     *deftype_action[5][4]={
  613.         {"Listing LHA archive...","Extracting files from LHA archive...",
  614.             "Listing LHA archive...","Extracting files from LHA archive..."},
  615.         {"Listing Arc archive...","Extracting files from Arc archive...",
  616.             "Listing Arc archive...","Extracting files from Arc archive..."},
  617.         {"Listing Zoo archive...","Extracting files from Zoo archive...",
  618.             "Listing Zoo archive...","Extracting files from Zoo archive..."},
  619.         {"Examining icon..."},
  620.         {"Reading file...","Copying file..."}},
  621.     deftype_delay[5][4]={
  622.         {0,2,0,2},
  623.         {0,2,0,2},
  624.         {-1,2,-1,2},
  625.         {2,2,2,2},
  626.         {2,2,2,2}};
  627.  
  628. unsigned char
  629.     defmenkeys1[10]={0,0x5f,0,0x33,0,0,0,0x17,0,0x10},
  630.     defmenqual1[10]={0,0,0,0x80,0,0,0,0x80,0,0x80},
  631.     defmenkeys2[9]={0x22,0x23,0x36,0,0,0,0,0,0},
  632.     defmenqual2[9]={0x80,0x80,0x80,0,0,0,0,0,0};
  633.  
  634. static struct DefaultGadFlag
  635.     default_gadflags[]={
  636.         {0x20,IEQUALIFIER_CONTROL,6,3},
  637.         {0x33,IEQUALIFIER_CONTROL,6,5},
  638.         {0x37,IEQUALIFIER_CONTROL,5,4},
  639.         {0x25,IEQUALIFIER_CONTROL|IEQUALIFIER_LSHIFT,4,1},
  640.         {0x16,IEQUALIFIER_CONTROL,1,4},
  641.         {0x33,IEQUALIFIER_CONTROL|IEQUALIFIER_LSHIFT,5,0},
  642.         {0x13,IEQUALIFIER_CONTROL,6,7},
  643.  
  644.         {0x36,IEQUALIFIER_CONTROL,6,3},
  645.         {0x37,IEQUALIFIER_CONTROL|IEQUALIFIER_LSHIFT,6,5},
  646.         {0,0,5,4},
  647.         {0x21,IEQUALIFIER_CONTROL|IEQUALIFIER_LSHIFT,4,1},
  648.         {0,0,1,0},
  649.         {0x22,IEQUALIFIER_CONTROL,5,0},
  650.         {0x25,IEQUALIFIER_CONTROL,6,7},
  651.  
  652.         {0x19,IEQUALIFIER_CONTROL,6,3},
  653.         {0x13,IEQUALIFIER_CONTROL|IEQUALIFIER_LSHIFT,6,5},
  654.         {0x23,IEQUALIFIER_CONTROL,5,4},
  655.         {0,0,1,0},
  656.         {0,0,1,0},
  657.         {0x14,IEQUALIFIER_CONTROL,5,0},
  658.         {0x21,IEQUALIFIER_CONTROL,6,7},
  659.  
  660.         {0x18,IEQUALIFIER_CONTROL,6,3},
  661.         {0,0,1,0},
  662.         {0x24,IEQUALIFIER_CONTROL,5,4},
  663.         {0,0,1,0},
  664.         {0,0,1,0},
  665.         {0x17,IEQUALIFIER_CONTROL,5,0},
  666.         {0x15,IEQUALIFIER_CONTROL,6,7},
  667.  
  668.         {0,0,1,0},
  669.         {0,0,1,0},
  670.         {0,0,1,0},
  671.         {0,0,1,0},
  672.         {0,0,1,0},
  673.         {0x12,IEQUALIFIER_CONTROL,5,0},
  674.         {0x12,IEQUALIFIER_CONTROL|IEQUALIFIER_LSHIFT,6,7},
  675.  
  676.         {0,0,1,0},
  677.         {0x22,IEQUALIFIER_CONTROL|IEQUALIFIER_LSHIFT,2,7},
  678.         {0,0,1,0},
  679.         {0,0,1,0},
  680.         {0,0,1,0},
  681.         {0,0,5,0},
  682.         {0x19,IEQUALIFIER_CONTROL|IEQUALIFIER_LSHIFT,6,7}};
  683.  
  684. static short
  685.     deftype_which[5][4]={
  686.         {FLAG_DOALL|FLAG_OUTFILE,FLAG_SCANDEST|FLAG_DOALL|FLAG_CDDEST|FLAG_OUTWIND,
  687.             FLAG_DOALL|FLAG_OUTFILE,FLAG_SCANDEST|FLAG_DOALL|FLAG_CDDEST|FLAG_OUTWIND},
  688.         {FLAG_DOALL|FLAG_OUTFILE,FLAG_SCANDEST|FLAG_DOALL|FLAG_CDDEST|FLAG_OUTWIND,
  689.             FLAG_DOALL|FLAG_OUTFILE,FLAG_SCANDEST|FLAG_DOALL|FLAG_CDDEST|FLAG_OUTWIND},
  690.         {FLAG_DOALL|FLAG_OUTWIND,FLAG_SCANDEST|FLAG_DOALL|FLAG_CDDEST|FLAG_OUTWIND,
  691.             FLAG_DOALL|FLAG_OUTWIND,FLAG_SCANDEST|FLAG_DOALL|FLAG_CDDEST|FLAG_OUTWIND},
  692.         {0,0,0,0},
  693.         {0,0,0,0}};
  694.  
  695. __asm __saveds DoDefaultConfig(register __a0 struct ConfigStuff *cstuff)
  696. {
  697.     int a,b,h,i;
  698.     struct Config *config;
  699.     struct dopusgadgetbanks *firstbank;
  700.     struct dopusfiletype *type;
  701.     char name[256];
  702.  
  703.     if (!(config=cstuff->config)) return(0);
  704.     DoFreeConfig(cstuff);
  705.  
  706.     if ((DoFindSystemFile("DirectoryOpus.DefCFG",name,256,SYSFILE_DATA)) &&
  707.         (DoReadConfig(name,cstuff))==1) return(1);
  708.  
  709.     /* Operation */
  710.  
  711.     config->copyflags=COPY_DATE|COPY_PROT|COPY_NOTE;
  712.     config->dateformat=DATE_DOS|DATE_SUBST|DATE_12HOUR;
  713.     config->existflags=REPLACE_ASK;
  714.     config->deleteflags=DELETE_ASK;
  715.     config->errorflags=ERROR_ENABLE_DOS|ERROR_ENABLE_OPUS;
  716.     config->generalflags=GENERAL_DRAG|GENERAL_DOUBLECLICK|GENERAL_ACTIVATE;
  717.     config->iconflags=ICONFLAG_MAKEDIRICON|ICONFLAG_DOUNTOICONS;
  718.  
  719.     for (h=0;h<2;h++) {
  720.         for (i=0;i<5;i++) config->displaypos[h][i]=i;
  721.         for (i=5;i<16;i++) config->displaypos[h][i]=-1;
  722.         config->displaylength[h][0]=28;
  723.         config->displaylength[h][1]=80;
  724.         config->displaylength[h][2]=40;
  725.         config->displaylength[h][3]=32;
  726.         config->displaylength[h][4]=32;
  727.         config->sortmethod[h]=0;
  728.         config->separatemethod[h]=1;
  729.     }
  730.     config->sortflags=0;
  731.     config->formatflags=0;
  732.  
  733.     config->dynamicflags=UPDATE_FREE|UPDATE_SCROLL|UPDATE_LEFTJUSTIFY|UPDATE_PROGRESSINDICATOR|UPDATE_REDRAW;
  734.  
  735.     /* System */
  736.  
  737.     strcpy(config->outputcmd,"NewCLI");
  738.     strcpy(config->output,"CON:20/10/600/180/Directory Opus Output");
  739.     strcpy(config->shellstartup,"Shell-Startup");
  740.     config->priority=0;
  741.  
  742.     config->icontype=ICON_MEMORY|ICON_DATE|ICON_TIME;
  743.     config->scrclktype=SCRCLOCK_MEMORY|SCRCLOCK_DATE|SCRCLOCK_TIME;
  744.  
  745.     config->bufcount=10;
  746.     config->dirflags=DIRFLAGS_FINDEMPTY|DIRFLAGS_REREADOLD|
  747.                                         DIRFLAGS_SMARTPARENT|DIRFLAGS_CHECKBUFS|
  748.                                         DIRFLAGS_AUTODISKC|DIRFLAGS_AUTODISKL;
  749.     config->showfree=SHOWFREE_KILO;
  750.  
  751.     config->hotkeycode=(USHORT)~0;
  752.     config->hotkeyqual=IEQUALIFIER_CONTROL|IEQUALIFIER_LSHIFT|IEQUALIFIER_LALT;
  753.     config->hotkeyflags=0;
  754.  
  755.     config->toolicon[0]=0;
  756.     config->projecticon[0]=0;
  757.     config->drawericon[0]=0;
  758.     config->defaulttool[0]=0;
  759.     config->addiconflags=0;
  760.  
  761.     config->loadexternal=0;
  762.     config->language[0]=0;
  763.  
  764.     config->hiddenbit=0;
  765.     config->showpat[0]=0;
  766.     config->hidepat[0]=0;
  767.     config->showpatparsed[0]=0;
  768.     config->hidepatparsed[0]=0;
  769.  
  770.     config->autodirs[0][0]=0;
  771.     config->autodirs[1][0]=0;
  772.     config->startupscript[0]=0;
  773.     config->uniconscript[0]=0;
  774.     config->configreturnscript[0]=0;
  775.  
  776.     config->viewbits=VIEWBITS_SHOWBLACK|VIEWBITS_TEXTBORDERS;
  777.     config->showdelay=0;
  778.     config->fadetime=2;
  779.     config->tabsize=8;
  780.  
  781.     /* Screen */
  782.  
  783.     for (a=0;a<3;a++) {
  784.         config->arrowpos[a]=2;
  785.         config->arrowsize[a]=8;
  786.     }
  787.     config->sliderwidth=10;
  788.     config->sliderheight=7;
  789.     config->stringheight=8;
  790.  
  791.     config->statusfg=1; config->statusbg=0;
  792.     config->disknameselfg=2; config->disknameselbg=7;
  793.     config->disknamefg=1; config->disknamebg=0;
  794.     config->dirsselfg=2; config->dirsselbg=3;
  795.     config->dirsfg=3; config->dirsbg=0;
  796.     config->filesselfg=2; config->filesselbg=1;
  797.     config->filesfg=1; config->filesbg=0;
  798.     config->slidercol=1; config->sliderbgcol=0;
  799.     config->arrowfg=1; config->arrowbg=0;
  800.     config->littlegadfg=1; config->littlegadbg=0;
  801.     config->clockfg=1; config->clockbg=0;
  802.     config->requestfg=1; config->requestbg=0;
  803.     config->gadgettopcol=2; config->gadgetbotcol=1;
  804.     config->stringfgcol=1; config->stringbgcol=0;
  805.     config->stringselfgcol=1; config->stringselbgcol=4;
  806.  
  807.     for (i=0;i<NUMFONTS;i++) {
  808.         config->fontsizes[i]=8;
  809.         strcpy(config->fontbufs[i],"topaz");
  810.     }
  811.  
  812.     config->generalscreenflags=SCR_GENERAL_TINYGADS|
  813.                                                             SCR_GENERAL_INDICATERMB|
  814.                                                             SCR_GENERAL_REQDRAG|
  815.                                                             SCR_GENERAL_NEWLOOKMENU|
  816.                                                             SCR_GENERAL_WINBORDERS;
  817.  
  818.     CopyMem((char *)defaultpalette,(char *)config->new_palette,sizeof(defaultpalette));
  819.  
  820.     config->screenmode=MODE_WORKBENCHCLONE;
  821.     config->scrdepth=3;
  822.     config->scrw=-1;
  823.     config->scrh=-1;
  824.     config->screenflags=0;
  825.  
  826.     config->scr_winx=0;
  827.     config->scr_winx=0;
  828.     config->scr_winw=-1;
  829.     config->scr_winh=-1;
  830.  
  831.     /* Misc Stuff */
  832.  
  833.     config->gadgetrows=6;
  834.  
  835.     config->iconx=252; config->icony=0;
  836.     config->wbwinx=0; config->wbwiny=0;
  837.     config->iconbutx=100; config->iconbuty=40;
  838.     config->config_x=-1; config->config_y=-1;
  839.  
  840.     for (a=0;a<2;a++) {
  841.         config->scrollborders[a].MinX=~0;
  842.         config->scrollborders[a].MaxX=~0;
  843.         config->scrollborders[a].MinY=~0;
  844.         config->scrollborders[a].MaxY=~0;
  845.     }
  846.  
  847.     config->windowdelta=0;
  848.     config->slider_pos=1;
  849.  
  850.     /* Buttons */
  851.  
  852.     for (i=0;i<42;i++) DoAssignGadget(cstuff,0,i,defgads[i],deffuncs[i]);
  853.     for (i=0;i<35;i++) DoAssignGadget(cstuff,0,i+42,revgads[i],revfuncs[i]);
  854.     for (i=78;i<GADCOUNT;i++) DoAssignGadget(cstuff,0,i,NULL,NULL);
  855.  
  856.     if (firstbank=cstuff->firstbank) {
  857.         for (i=0;i<GADCOUNT;i++) {
  858.             firstbank->gadgets[i].which=0;
  859.             firstbank->gadgets[i].type=0;
  860.             firstbank->gadgets[i].stack=4000;
  861.             firstbank->gadgets[i].pri=0;
  862.             firstbank->gadgets[i].delay=2;
  863.             if (i<42) {
  864.                 firstbank->gadgets[i].key=default_gadflags[i].code;
  865.                 firstbank->gadgets[i].qual=default_gadflags[i].qual;
  866.                 firstbank->gadgets[i].fpen=default_gadflags[i].fpen;
  867.                 firstbank->gadgets[i].bpen=default_gadflags[i].bpen;
  868.             }
  869.             else {
  870.                 firstbank->gadgets[i].fpen=1;
  871.                 firstbank->gadgets[i].bpen=0;
  872.                 if (i==57) {
  873.                     firstbank->gadgets[i].key=0x28;
  874.                     firstbank->gadgets[i].qual=IEQUALIFIER_CONTROL;
  875.                 }
  876.                 else if (i==68) {
  877.                     firstbank->gadgets[i].key=0x17;
  878.                     firstbank->gadgets[i].qual=IEQUALIFIER_CONTROL|IEQUALIFIER_LSHIFT;
  879.                 }
  880.                 else {
  881.                     firstbank->gadgets[i].key=0;
  882.                     firstbank->gadgets[i].qual=0;
  883.                 }
  884.             }
  885.         }
  886.         firstbank->gadgets[34].which=FLAG_ASYNC|FLAG_CDSOURCE;
  887.         firstbank->gadgets[76].which=FLAG_ASYNC|FLAG_CDSOURCE;
  888.     }
  889.     cstuff->curbank=firstbank;
  890.  
  891.     /* Menus */
  892.  
  893.     strcpy(config->menutit[0],"Project");
  894.     strcpy(config->menutit[1],"Function");
  895.     for (i=2;i<5;i++) config->menutit[i][0]=0;
  896.  
  897.     for (i=0;i<9;i++) {
  898.         DoAssignMenu(cstuff,i,defmenus1[i],deffuncs1[i]);
  899.         config->menu[i].key=defmenkeys1[i];
  900.         config->menu[i].qual=defmenqual1[i];
  901.     }
  902.     for (i=20;i<29;i++) {
  903.         h=i-20;
  904.         DoAssignMenu(cstuff,i,defmenus2[h],deffuncs2[h]);
  905.         config->menu[i].key=defmenkeys2[h];
  906.         config->menu[i].qual=defmenqual2[h];
  907.     }
  908.     for (i=26;i<29;i++) {
  909.         config->menu[i].which=FLAG_OUTWIND|FLAG_CDSOURCE|FLAG_DOALL|FLAG_SCANDEST|((i==27)?0:FLAG_RECURSE);
  910.         config->menu[i].delay=-1;
  911.     }
  912.  
  913.     /* Drives */
  914.  
  915.     DoGetDevices(cstuff);
  916.  
  917.     for (i=0;i<DRIVECOUNT;i++) {
  918.         config->drive[i].key=0;
  919.         config->drive[i].qual=0;
  920.         config->drive[i].fpen=1;
  921.         config->drive[i].bpen=0;
  922.     }
  923.  
  924.     /* Filetypes */
  925.  
  926.     for (i=0;i<5;i++) {
  927.         if ((type=(struct dopusfiletype *)
  928.             LAllocRemember(&cstuff->typekey,sizeof(struct dopusfiletype),MEMF_CLEAR))) {
  929.             strcpy(type->type,deftype_type[i]);
  930.             strcpy(type->typeid,deftype_typeid[i]);
  931.             if (type->recognition=LAllocRemember(&cstuff->typekey,strlen(deftype_recog[i])+1,0))
  932.                 strcpy(type->recognition,deftype_recog[i]);
  933.             for (a=0;a<4;a++) {
  934.                 if (deftype_funcs[i][a]) {
  935.                     b=deftype_funcpos[i][a];
  936.                     strcpy(type->actionstring[b],deftype_action[i][a]);
  937.                     type->which[b]=deftype_which[i][a];
  938.                     type->delay[b]=deftype_delay[i][a];
  939.                     type->stack[b]=4000;
  940.                     if (type->function[b]=LAllocRemember(&cstuff->typekey,strlen(deftype_funcs[i][a])+1,0))
  941.                     strcpy(type->function[b],deftype_funcs[i][a]);
  942.                 }
  943.             }
  944.             linkinnewfiletype(cstuff,type);
  945.         }
  946.     }
  947.     return(1);
  948. }
  949.  
  950. readline(buf,pos,buf1,size)
  951. char *buf;
  952. int pos;
  953. char *buf1;
  954. int size;
  955. {
  956.     int a;
  957.  
  958.     for (a=0;a<4096;a++) {
  959.         if (size==pos || buf[pos]==0) {
  960.             buf1[a]=0;
  961.             if (size==pos) return(-1);
  962.             return(pos+1);
  963.         }
  964.         buf1[a]=buf[pos];
  965.         ++pos;
  966.     }
  967.     buf1[pos]=0;
  968.     return(pos);
  969. }
  970.  
  971. __asm __saveds DoGetDevices(register __a0 struct ConfigStuff *cstuff)
  972. {
  973.     struct DeviceList *devlist;
  974.     struct RootNode *rootnode;
  975.     struct DosInfo *dosinfo;
  976.     struct Config *config;
  977.     char devname[16],pathname[256];
  978.     int gap,i,j,k,a,p,l,d;
  979.  
  980.     if (!(config=cstuff->config)) return(0);
  981.     rootnode=(struct RootNode *) DOSBase->dl_Root;
  982.     dosinfo=(struct DosInfo *) BADDR(rootnode->rn_Info);
  983.     devlist=(struct DeviceList *) BADDR(dosinfo->di_DevInfo);
  984.     a=0;
  985.     while (devlist) {
  986.         if (devlist->dl_Type==DLT_DEVICE && devlist->dl_Task) {
  987.             BtoCStr((BPTR)devlist->dl_Name,pathname,256);
  988.             LStrCat(pathname,":");
  989.             strncpy(devname,pathname,15); devname[15]=0;
  990.             DoAssignDrive(cstuff,a,devname,pathname);
  991.             ++a;
  992.             if (a==DRIVECOUNT) break;
  993.         }
  994.         devlist=(struct DeviceList *) BADDR(devlist->dl_Next);
  995.     }
  996.     for (gap=a/2;gap>0;gap/=2) {
  997.         for (i=gap;i<a;i++) {
  998.             for (j=i-gap;j>=0;j-=gap) {
  999.                 k=j+gap;
  1000.                 if (LStrCmpI(config->drive[j].name,config->drive[k].name)<=0) break;
  1001.                 SwapMem((char *)&config->drive[j],(char *)&config->drive[k],sizeof(struct dopusfunction));
  1002.             }
  1003.         }
  1004.     }
  1005.     d=a;
  1006.     if (a<DRIVECOUNT) {
  1007.         devlist=(struct DeviceList *) BADDR(dosinfo->di_DevInfo);
  1008.         while (devlist) {
  1009.             if (devlist->dl_Type==DLT_DIRECTORY) {
  1010.                 BtoCStr((BPTR)devlist->dl_Name,pathname,256);
  1011.                 LStrCat(pathname,":");
  1012.                 strncpy(devname,pathname,15); devname[15]=0;
  1013.                 DoAssignDrive(cstuff,a,devname,pathname);
  1014.                 ++a;
  1015.                 if (a==DRIVECOUNT) break;
  1016.             }
  1017.             devlist=(struct DeviceList *) BADDR(devlist->dl_Next);
  1018.         }
  1019.     }
  1020.     p=a-d;
  1021.     for (gap=p/2;gap>0;gap/=2) {
  1022.         for (i=gap;i<p;i++) {
  1023.             for (j=i-gap;j>=0;j-=gap) {
  1024.                 k=j+gap+d; l=j+d;
  1025.                 if (LStrCmpI(config->drive[l].name,config->drive[k].name)<=0) break;
  1026.                 SwapMem((char *)&config->drive[l],(char *)&config->drive[k],sizeof(struct dopusfunction));
  1027.             }
  1028.         }
  1029.     }
  1030.     if (a<DRIVECOUNT) {
  1031.         for (i=a;i<DRIVECOUNT;i++) DoAssignDrive(cstuff,i,NULL,NULL);
  1032.     }
  1033. }
  1034.  
  1035. void __asm __saveds DoAssignGadget(register __a0 struct ConfigStuff *cstuff,
  1036.     register __d0 int bk,
  1037.     register __d1 int gad,
  1038.     register __a1 char *name,
  1039.     register __a2 char *func)
  1040. {
  1041.     struct dopusgadgetbanks *bank,*temp;
  1042.     int a;
  1043.  
  1044.     bank=cstuff->firstbank;
  1045.     for (a=0;a<bk;a++) {
  1046.         if (!bank || !bank->next) break;
  1047.         bank=bank->next;
  1048.     }
  1049.     if (a<bk || !bank) {
  1050.         if (!(temp=AllocMem(sizeof(struct dopusgadgetbanks),MEMF_CLEAR))) return;
  1051.         if (bank) bank->next=temp;
  1052.         else cstuff->firstbank=temp;
  1053.         bank=temp;
  1054.     }
  1055.  
  1056.     if (name!=(char *)-1) {
  1057.         freestring(bank->gadgets[gad].name);
  1058.         bank->gadgets[gad].name=NULL;
  1059.         if (name && name[0]) bank->gadgets[gad].name=getstringcopy(name);
  1060.     }
  1061.     if (func!=(char *)-1) {
  1062.         freestring(bank->gadgets[gad].function);
  1063.         bank->gadgets[gad].function=NULL;
  1064.         if (func && func[0]) bank->gadgets[gad].function=getstringcopy(func);
  1065.     }
  1066. }
  1067.  
  1068. void __asm __saveds DoAssignMenu(register __a0 struct ConfigStuff *cstuff,
  1069.     register __d0 int men,
  1070.     register __a1 char *name,
  1071.     register __a2 char *func)
  1072. {
  1073.     struct Config *config;
  1074.  
  1075.     if (!(config=cstuff->config)) return;
  1076.     if (name!=(char *)-1) {
  1077.         freestring(config->menu[men].name);
  1078.         config->menu[men].name=NULL;
  1079.         if (name && name[0]) config->menu[men].name=getstringcopy(name);
  1080.     }
  1081.     if (func!=(char *)-1) {
  1082.         freestring(config->menu[men].function);
  1083.         config->menu[men].function=NULL;
  1084.         if (func && func[0]) config->menu[men].function=getstringcopy(func);
  1085.     }
  1086. }
  1087.  
  1088. void DoAssignDrive(cstuff,drv,name,path)
  1089. struct ConfigStuff *cstuff;
  1090. int drv;
  1091. char *name,*path;
  1092. {
  1093.     struct Config *config;
  1094.  
  1095.     if (!(config=cstuff->config)) return;
  1096.     if (name!=(char *)-1) {
  1097.         if (!name) config->drive[drv].name[0]=0;
  1098.         else strcpy(config->drive[drv].name,name);
  1099.     }
  1100.     if (path!=(char *)-1) {
  1101.         freestring(config->drive[drv].function);
  1102.         config->drive[drv].function=NULL;
  1103.         if (path && path[0]) config->drive[drv].function=getstringcopy(path);
  1104.     }
  1105. }
  1106.  
  1107. void linkinnewfiletype(cstuff,temp)
  1108. struct ConfigStuff *cstuff;
  1109. struct dopusfiletype *temp;
  1110. {
  1111.     struct dopusfiletype *pos;
  1112.  
  1113.     temp->next=NULL;
  1114.     if (!(pos=cstuff->firsttype)) cstuff->firsttype=temp;
  1115.     else {
  1116.         while (pos->next) {
  1117.             if (strcmp(pos->next->type,"Default")==0) {
  1118.                 temp->next=pos->next;
  1119.                 break;
  1120.             }
  1121.             pos=pos->next;
  1122.         }
  1123.         pos->next=temp;
  1124.     }
  1125. }
  1126.  
  1127. void __asm __saveds DoFreeConfig(register __a0 struct ConfigStuff *cstuff)
  1128. {
  1129.     int a;
  1130.     struct Config *config;
  1131.     struct dopusgadgetbanks *bank,*temp;
  1132.     struct dopushotkey *hotkey,*temphot;
  1133.  
  1134.     if (!(config=cstuff->config)) return;
  1135.  
  1136.     for (a=0;a<MENUCOUNT;a++) {
  1137.         DoAssignMenu(cstuff,a,NULL,NULL);
  1138.         config->menu[a].which=0; config->menu[a].type=0;
  1139.         config->menu[a].stack=4000; config->menu[a].pri=0;
  1140.         config->menu[a].delay=2;
  1141.         config->menu[a].fpen=0; config->menu[a].bpen=1;
  1142.         config->menu[a].key=0; config->menu[a].qual=0;
  1143.     }
  1144.     for (a=0;a<DRIVECOUNT;a++) {
  1145.         DoAssignDrive(cstuff,a,NULL,NULL);
  1146.         config->drive[a].key=config->drive[a].qual=0;
  1147.         config->drive[a].fpen=3; config->drive[a].bpen=0;
  1148.     }
  1149.  
  1150.     bank=cstuff->firstbank;
  1151.     while (bank) {
  1152.         for (a=0;a<GADCOUNT;a++) {
  1153.             freestring(bank->gadgets[a].name);
  1154.             freestring(bank->gadgets[a].function);
  1155.         }
  1156.         temp=bank->next;
  1157.         FreeMem(bank,sizeof(struct dopusgadgetbanks));
  1158.         bank=temp;
  1159.     }
  1160.     cstuff->firstbank=cstuff->curbank=NULL;
  1161.  
  1162.     hotkey=cstuff->firsthotkey;
  1163.     while (hotkey) {
  1164.         temphot=hotkey->next;
  1165.         freestring(hotkey->func.function);
  1166.         FreeMem(hotkey,sizeof(struct dopushotkey));
  1167.         hotkey=temphot;
  1168.     }
  1169.     cstuff->firsthotkey=NULL;
  1170.  
  1171.     LFreeRemember(&cstuff->typekey);
  1172.     cstuff->firsttype=NULL;
  1173. }
  1174.  
  1175. void freestring(str)
  1176. char *str;
  1177. {
  1178.     if (str) FreeMem(str,strlen(str)+1);
  1179. }
  1180.  
  1181. __asm __saveds DoCheckConfig(register __a0 struct ConfigStuff *cstuff)
  1182. {
  1183.     struct Config *config;
  1184.  
  1185.     if (!(config=cstuff->config)) return(0);
  1186.  
  1187.     if (config->sliderheight<5) config->sliderheight=5;
  1188.     else if (config->sliderheight>49) config->sliderheight=49;
  1189.     if (config->sliderwidth<8) config->sliderwidth=8;
  1190.     else if (config->sliderwidth>108) config->sliderwidth=108;
  1191. }
  1192.  
  1193. char *look_dirs[]={
  1194.     "C:","DOpus:C/",
  1195.     "S:","DOpus:S/",
  1196.     "LIBS:","DOpus:Libs/",
  1197.     "REXX:","DOpus:Rexx/",
  1198.     "C:","DOpus:Modules/",
  1199.     "S:","DOpus:Requesters/"};
  1200.  
  1201. __asm __saveds DoFindSystemFile(register __a0 char *name,
  1202.     register __a1 char *buf,
  1203.     register __d0 int size,
  1204.     register __d1 int type)
  1205. {
  1206.     char temp[256];
  1207.  
  1208. tryloop:
  1209.     LStrnCpy(temp,name,256);
  1210.     if (DOSBase->dl_lib.lib_Version<36 ||
  1211.         !(FindSegment(temp,NULL,0))) {
  1212.         if (DoCheckExist(temp,NULL)>=0) {
  1213.             int a;
  1214.  
  1215.             for (a=0;a<2;a++) {
  1216.                 StrCombine(temp,look_dirs[(type*2)+a],name,256);
  1217.                 if (DoCheckExist(temp,NULL)<0) break;
  1218.             }
  1219.             if (a==2) temp[0]=0;
  1220.         }
  1221.         else {
  1222.             BPTR lock;
  1223.  
  1224.             if (lock=Lock("",ACCESS_READ)) {
  1225.                 DoPathName(lock,temp,256);
  1226.                 UnLock(lock);
  1227.                 DoTackOn(temp,name,256);
  1228.             }
  1229.         }
  1230.     }
  1231.     if (temp[0]) {
  1232.         LStrnCpy(buf,temp,size);
  1233.         return(1);
  1234.     }
  1235.     else if (type==SYSFILE_MODULE) {
  1236.         struct DOpusSimpleRequest req;
  1237.         char reqbuf[300];
  1238.         static char *req_gads[3]={"Try Again","Cancel",NULL};
  1239.         static int req_rets[2]={1,0};
  1240.  
  1241.         LSprintf(reqbuf,"Unable to find the file \"%s\"\nin either the C: directory or the\n\
  1242. DOPUS:Modules/ directory. Insert DOpus disk\nif necessary and select Try Again, or\n\
  1243. Cancel to abort the operation",name);
  1244.  
  1245.         req.text=reqbuf;
  1246.         req.gads=req_gads;
  1247.         req.rets=req_rets;
  1248.         req.hi=-1; req.lo=-1;
  1249.         req.fg=-1; req.bg=-1;
  1250.         req.strbuf=NULL;
  1251.         req.flags=0;
  1252.         req.font=NULL;
  1253.         if (DoSimpleRequest(NULL,&req)) goto tryloop;
  1254.     }
  1255.     LStrnCpy(buf,name,size);
  1256.     return(0);
  1257. }
  1258.